#include "mainwindow.h"
#include <QStatusBar>

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{

    // 创建串口对象
    serial = new QSerialPort(this);

    // 创建串口扫描定时器
    portScanTimer = new QTimer(this);
    portScanTimer->setInterval(5000); // 每5秒扫描一次

    // 设置UI
    setupUI();
    setupConnections();

    // 初始扫描串口
    updateSerialPortList();

    // 启动定时器扫描串口
    connect(portScanTimer, &QTimer::timeout, this, &MainWindow::updateSerialPortList);
    portScanTimer->start();

    // 设置窗口标题和大小
    setWindowTitle("温室监控系统");
    resize(800, 600);
}

MainWindow::~MainWindow()
{
    // 关闭串口连接
    if (serial->isOpen()) {
        serial->close();
    }

    delete serial;
    delete portScanTimer;
}

void MainWindow::setupUI()
{
    // 创建主布局
    QWidget *centralWidget = new QWidget(this);
    QVBoxLayout *mainLayout = new QVBoxLayout(centralWidget);
    setCentralWidget(centralWidget);

    // =============== 串口控制区域 ===============
    QGroupBox *serialGroup = new QGroupBox("串口控制", this);
    QHBoxLayout *serialLayout = new QHBoxLayout(serialGroup);

    serialLayout->addWidget(new QLabel("串口:"));
    portComboBox = new QComboBox(this);
    serialLayout->addWidget(portComboBox);

    connectButton = new QPushButton("连接", this);
    disconnectButton = new QPushButton("断开", this);
    disconnectButton->setEnabled(false);

    serialLayout->addWidget(connectButton);
    serialLayout->addWidget(disconnectButton);

    mainLayout->addWidget(serialGroup);

    // =============== 数据显示区域 ===============
    QGridLayout *dataLayout = new QGridLayout();

    // 温度显示
    QGroupBox *tempGroup = new QGroupBox("温度", this);
    QVBoxLayout *tempVLayout = new QVBoxLayout(tempGroup);
    temperatureLabel = new QLabel("--.- °C", this);
    temperatureLabel->setAlignment(Qt::AlignCenter);
    temperatureLabel->setStyleSheet("font-size: 24px; font-weight: bold;");
    temperatureBar = new QProgressBar(this);
    temperatureBar->setRange(0, 50);
    temperatureBar->setValue(0);
    temperatureBar->setFormat("%v °C");
    tempVLayout->addWidget(temperatureLabel);
    tempVLayout->addWidget(temperatureBar);
    dataLayout->addWidget(tempGroup, 0, 0);

    // 湿度显示
    QGroupBox *humGroup = new QGroupBox("湿度", this);
    QVBoxLayout *humVLayout = new QVBoxLayout(humGroup);
    humidityLabel = new QLabel("--.- %", this);
    humidityLabel->setAlignment(Qt::AlignCenter);
    humidityLabel->setStyleSheet("font-size: 24px; font-weight: bold;");
    humidityBar = new QProgressBar(this);
    humidityBar->setRange(0, 100);
    humidityBar->setValue(0);
    humidityBar->setFormat("%v %");
    humVLayout->addWidget(humidityLabel);
    humVLayout->addWidget(humidityBar);
    dataLayout->addWidget(humGroup, 0, 1);

    // 光照强度显示
    QGroupBox *lightGroup = new QGroupBox("光照强度", this);
    QVBoxLayout *lightVLayout = new QVBoxLayout(lightGroup);
    lightLabel = new QLabel("----", this);
    lightLabel->setAlignment(Qt::AlignCenter);
    lightLabel->setStyleSheet("font-size: 24px; font-weight: bold;");
    lightBar = new QProgressBar(this);
    lightBar->setRange(0, 4095);
    lightBar->setValue(0);
    lightBar->setFormat("%v lux");
    lightVLayout->addWidget(lightLabel);
    lightVLayout->addWidget(lightBar);
    dataLayout->addWidget(lightGroup, 1, 0);

    // 土壤湿度显示
    QGroupBox *soilGroup = new QGroupBox("土壤湿度", this);
    QVBoxLayout *soilVLayout = new QVBoxLayout(soilGroup);
    soilMoistureLabel = new QLabel("----", this);
    soilMoistureLabel->setAlignment(Qt::AlignCenter);
    soilMoistureLabel->setStyleSheet("font-size: 24px; font-weight: bold;");
    soilMoistureBar = new QProgressBar(this);
    soilMoistureBar->setRange(0, 100);
    soilMoistureBar->setValue(0);
    soilMoistureBar->setFormat("%v %");
    soilVLayout->addWidget(soilMoistureLabel);
    soilVLayout->addWidget(soilMoistureBar);
    dataLayout->addWidget(soilGroup, 1, 1);

    mainLayout->addLayout(dataLayout);

    // =============== 调试信息区域 ===============
    QGroupBox *debugGroup = new QGroupBox("调试信息", this);
    QVBoxLayout *debugLayout = new QVBoxLayout(debugGroup);
    debugTextEdit = new QTextEdit(this);
    debugTextEdit->setMaximumHeight(120);  // 限制高度
    debugTextEdit->setReadOnly(true);      // 只读
    debugTextEdit->setFont(QFont("Consolas", 9)); // 设置等宽字体
    debugLayout->addWidget(debugTextEdit);

    // 添加清空按钮
    QPushButton *clearDebugButton = new QPushButton("清空调试信息", this);
    connect(clearDebugButton, &QPushButton::clicked, debugTextEdit, &QTextEdit::clear);
    debugLayout->addWidget(clearDebugButton);

    mainLayout->addWidget(debugGroup);

    // =============== 状态栏 ===============
    statusBar()->showMessage("未连接串口");
}

void MainWindow::setupConnections()
{
    // 串口控制连接
    connect(connectButton, &QPushButton::clicked, this, &MainWindow::onConnectButtonClicked);
    connect(disconnectButton, &QPushButton::clicked, this, &MainWindow::onDisconnectButtonClicked);
    connect(serial, &QSerialPort::readyRead, this, &MainWindow::readSerialData);
    connect(serial, &QSerialPort::errorOccurred, [this](QSerialPort::SerialPortError error) {
        if (error != QSerialPort::NoError) {
            statusBar()->showMessage("串口错误: " + serial->errorString());
            onDisconnectButtonClicked();
        }
    });
}

void MainWindow::updateSerialPortList()
{
    QString currentPort = portComboBox->currentText();
    portComboBox->clear();

    // 获取所有可用串口
    const auto ports = QSerialPortInfo::availablePorts();
    for (const QSerialPortInfo &port : ports) {
        portComboBox->addItem(port.portName() + " - " + port.description());
    }

    // 恢复之前选择的串口
    int index = portComboBox->findText(currentPort);
    if (index >= 0) {
        portComboBox->setCurrentIndex(index);
    }
}

void MainWindow::onConnectButtonClicked()
{
    if (portComboBox->currentText().isEmpty()) {
        statusBar()->showMessage("请选择串口");
        return;
    }

    // 提取串口名称
    QString portName = portComboBox->currentText().split(" -")[0];

    // 配置串口
    serial->setPortName(portName);
    serial->setBaudRate(QSerialPort::Baud9600);
    serial->setDataBits(QSerialPort::Data8);
    serial->setParity(QSerialPort::NoParity);
    serial->setStopBits(QSerialPort::OneStop);
    serial->setFlowControl(QSerialPort::NoFlowControl);

    // 尝试打开串口
    if (serial->open(QIODevice::ReadWrite)) {
        statusBar()->showMessage("串口连接成功: " + portName);
        updateConnectionStatus(true);
    } else {
        statusBar()->showMessage("串口连接失败: " + serial->errorString());
    }
}

void MainWindow::onDisconnectButtonClicked()
{
    if (serial->isOpen()) {
        serial->close();
    }
    statusBar()->showMessage("串口已断开");
    updateConnectionStatus(false);
}

void MainWindow::updateConnectionStatus(bool connected)
{
    connectButton->setEnabled(!connected);
    disconnectButton->setEnabled(connected);
    portComboBox->setEnabled(!connected);


    // 如果断开连接，重置状态显示
    if (!connected) {
        temperatureLabel->setText("--.- °C");
        humidityLabel->setText("--.- %");
        lightLabel->setText("----");
        soilMoistureLabel->setText("----");

        temperatureBar->setValue(0);
        humidityBar->setValue(0);
        lightBar->setValue(0);
        soilMoistureBar->setValue(0);
    }
}

void MainWindow::readSerialData()
{
    static QByteArray buffer;

    if (serial->bytesAvailable() > 0) {
        QByteArray data = serial->readAll();
        buffer.append(data);

        // 添加调试信息：显示原始数据
        if (debugTextEdit) {
            debugTextEdit->append("收到原始数据: " + data.toHex(' ').toUpper());
        }

        // 查找完整的行数据（以换行符结束）
        while (buffer.contains('\n')) {
            int pos = buffer.indexOf('\n');
            QByteArray frame = buffer.left(pos).trimmed();
            buffer = buffer.mid(pos + 1);

            if (!frame.isEmpty()) {
                // 添加调试信息：显示完整帧
                if (debugTextEdit) {
                    debugTextEdit->append("完整帧: " + frame);
                }

                // 检查是否是MQTT发布命令，包含传感器数据
                if (frame.startsWith("AT+MQTTPUB") && frame.contains("attributes")) {
                    if (debugTextEdit) {
                        debugTextEdit->append("检测到MQTT传感器数据");
                    }

                    // 从MQTT命令中提取JSON数据
                    int jsonStart = frame.indexOf("{\\");
                    int jsonEnd = frame.lastIndexOf("}");

                    if (jsonStart != -1 && jsonEnd != -1 && jsonEnd > jsonStart) {
                        QByteArray jsonData = frame.mid(jsonStart, jsonEnd - jsonStart + 1);

                        if (debugTextEdit) {
                            debugTextEdit->append("提取的原始JSON数据: " + jsonData);
                        }

                        // 处理转义字符：将 \" 替换为 "
                        jsonData.replace("\\\"", "\"");
                        // 处理转义逗号：将 \, 替换为 ,
                        jsonData.replace("\\,", ",");
                        // 处理其他转义字符
                        jsonData.replace("\\\\", "\\");
                        jsonData.replace("\\/", "/");
                        jsonData.replace("\\b", "\b");
                        jsonData.replace("\\f", "\f");
                        jsonData.replace("\\n", "\n");
                        jsonData.replace("\\r", "\r");
                        jsonData.replace("\\t", "\t");

                        if (debugTextEdit) {
                            debugTextEdit->append("处理后的JSON数据: " + jsonData);
                        }

                        // 尝试解析JSON数据
                        QJsonParseError error;
                        QJsonDocument doc = QJsonDocument::fromJson(jsonData, &error);

                        if (error.error == QJsonParseError::NoError && doc.isObject()) {
                            QJsonObject jsonObj = doc.object();

                            if (debugTextEdit) {
                                debugTextEdit->append("JSON解析成功");
                                debugTextEdit->append("包含字段: " + QStringList(jsonObj.keys()).join(", "));
                            }

                            // 处理传感器数据
                            if (jsonObj.contains("temperature") || jsonObj.contains("humidity") ||
                                jsonObj.contains("light_intensity") || jsonObj.contains("soil_moisture")) {
                                if (debugTextEdit) {
                                    debugTextEdit->append("识别为传感器数据，开始处理...");
                                }
                                processSensorData(jsonObj);
                            } else {
                                if (debugTextEdit) {
                                    debugTextEdit->append("不是传感器数据，跳过");
                                }
                            }
                        } else {
                            if (debugTextEdit) {
                                debugTextEdit->append("JSON解析错误: " + error.errorString());
                                debugTextEdit->append("错误位置: " + QString::number(error.offset));
                                debugTextEdit->append("解析的数据: " + jsonData);
                            }
                        }
                    } else {
                        if (debugTextEdit) {
                            debugTextEdit->append("无法从MQTT命令中提取JSON数据");
                        }
                    }
                }
                // 过滤掉其他AT命令响应
                else if (frame.startsWith("AT+") || frame.startsWith("OK") ||
                         frame.startsWith("ERROR") || frame.contains("+IPD")) {
                    if (debugTextEdit) {
                        debugTextEdit->append("过滤掉: " + frame);
                    }
                }
                // 检查是否是直接的JSON数据（备用方案）
                else if (frame.startsWith("{")) {
                    if (debugTextEdit) {
                        debugTextEdit->append("尝试解析直接JSON: " + frame);
                    }

                    QJsonParseError error;
                    QJsonDocument doc = QJsonDocument::fromJson(frame, &error);

                    if (error.error == QJsonParseError::NoError && doc.isObject()) {
                        QJsonObject jsonObj = doc.object();

                        if (debugTextEdit) {
                            debugTextEdit->append("直接JSON解析成功");
                        }

                        if (jsonObj.contains("temperature") || jsonObj.contains("humidity") ||
                            jsonObj.contains("light_intensity") || jsonObj.contains("soil_moisture")) {
                            processSensorData(jsonObj);
                        }
                    }
                }
                // 其他未知格式数据
                else {
                    if (debugTextEdit) {
                        debugTextEdit->append("未知格式数据: " + frame);
                    }
                }
            }
        }

        // 限制调试信息行数，避免内存占用过多
        if (debugTextEdit && debugTextEdit->document()->lineCount() > 100) {
            QTextCursor cursor = debugTextEdit->textCursor();
            cursor.movePosition(QTextCursor::Start);
            cursor.movePosition(QTextCursor::Down, QTextCursor::KeepAnchor, 50);
            cursor.removeSelectedText();
        }
    }
}

void MainWindow::processSensorData(const QJsonObject &data)
{
    // 添加调试信息：显示处理的数据
    if (debugTextEdit) {
        debugTextEdit->append("开始处理传感器数据...");
    }

    bool dataUpdated = false;

    // 更新温度
    if (data.contains("temperature")) {
        float temp = data["temperature"].toDouble();
        temperatureLabel->setText(QString::number(temp, 'f', 1) + " °C");
        updateProgressBar(temperatureBar, temp, 0, 50);
        if (debugTextEdit) {
            debugTextEdit->append("温度: " + QString::number(temp, 'f', 1) + " °C");
        }
        dataUpdated = true;
    }

    // 更新湿度
    if (data.contains("humidity")) {
        float hum = data["humidity"].toDouble();
        humidityLabel->setText(QString::number(hum, 'f', 1) + " %");
        updateProgressBar(humidityBar, hum, 0, 100);
        if (debugTextEdit) {
            debugTextEdit->append("湿度: " + QString::number(hum, 'f', 1) + " %");
        }
        dataUpdated = true;
    }

    // 更新光照强度 - 修正value值
    if (data.contains("light_intensity")) {
        int light = data["light_intensity"].toInt();
        lightLabel->setText(QString::number(light) + " lux");
        updateProgressBar(lightBar, light, 0, 4000);
        if (debugTextEdit) {
            debugTextEdit->append("光照强度: " + QString::number(light) + " lux");
        }
        dataUpdated = true;
    }

    // 更新土壤湿度
    if (data.contains("soil_moisture")) {
        float soil = data["soil_moisture"].toDouble();
        soilMoistureLabel->setText(QString::number(soil, 'f', 1) + " %");
        updateProgressBar(soilMoistureBar, soil, 0, 100);
        if (debugTextEdit) {
            debugTextEdit->append("土壤湿度: " + QString::number(soil, 'f', 1) + " %");
        }
        dataUpdated = true;
    }

    // 添加调试信息：显示处理完成
    if (debugTextEdit) {
        if (dataUpdated) {
            debugTextEdit->append("传感器数据更新成功");
        } else {
            debugTextEdit->append("没有有效的传感器数据");
        }
        debugTextEdit->append("----------------------------------------");
    }
}

void MainWindow::updateProgressBar(QProgressBar *bar, float value, float min, float max)
{
    // 确保值在范围内
    if (value < min) value = min;
    if (value > max) value = max;

    bar->setValue(static_cast<int>(value));

    // 根据值设置不同的颜色
    if (bar == temperatureBar) {
        if (value < 10) bar->setStyleSheet("QProgressBar::chunk { background-color: #3498db; } QProgressBar { text-align: center; }");
        else if (value < 25) bar->setStyleSheet("QProgressBar::chunk { background-color: #2ecc71; } QProgressBar { text-align: center; }");
        else if (value < 35) bar->setStyleSheet("QProgressBar::chunk { background-color: #f39c12; } QProgressBar { text-align: center; }");
        else bar->setStyleSheet("QProgressBar::chunk { background-color: #e74c3c; } QProgressBar { text-align: center; }");
    } else if (bar == humidityBar) {
        if (value < 30) bar->setStyleSheet("QProgressBar::chunk { background-color: #e74c3c; } QProgressBar { text-align: center; }");
        else if (value < 70) bar->setStyleSheet("QProgressBar::chunk { background-color: #2ecc71; } QProgressBar { text-align: center; }");
        else bar->setStyleSheet("QProgressBar::chunk { background-color: #f39c12; } QProgressBar { text-align: center; }");
    } else {
        bar->setStyleSheet("QProgressBar { text-align: center; }");
    }
}
